package org.example.myAop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author 莫磊
 * @date 2025/7/30
 * @description 日志切面, 切面类需要使用@Aspect注解标识
 */
@Aspect
@Component
// 多个切面使用这个控制执行顺序，数字越小优先级越高
@Order(1)
public class LogAspect {
	 // 切面 = 通知 + 切点

	/**
	 * 切点表达式
	 * execution([访问控制权限修饰符] 返回值类型 [全限定类名]方法名(参数列表) [异常列表])
	 */

	/**
	 * 定义通用切点表达式
	 */
	@Pointcut("execution(* org.example.myAop.service..*(..))")
	public void pointCut() {}

	@Before("pointCut()")
	public void beforeAdvice(JoinPoint joinPoint) {
		System.out.println("前置通知" + joinPoint.getSignature().getName());
	}

	@AfterReturning("pointCut()")
	public void afterReturningAdvice() {
		System.out.println("后置通知");
	}

	@Around("pointCut()")
	public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕通知开始");
		Object obj = joinPoint.proceed();
		System.out.println("环绕通知结束");
		return obj;
	}

	@After("pointCut()")
	public void afterAdvice() {
		System.out.println("最终通知");
	}

	@AfterThrowing("pointCut()")
	public void afterThrowingAdvice() {
		System.out.println("异常通知");
	}

}
